package com.jimmy.medical.controller;

import com.jimmy.medical.entity.Order;
import com.jimmy.medical.entity.RechargeRecord;
import com.jimmy.medical.model.AjaxResult;
import com.jimmy.medical.repository.MemberRepository;
import com.jimmy.medical.repository.OrderRepository;
import com.jimmy.medical.repository.RechargeRecordRepository;
import com.jimmy.medical.util.AjaxUtils;
import com.jimmy.medical.util.Func_T;
import com.jimmy.medical.wechat.WeChatPayRequest;
import com.jimmy.medical.wechat.WxPay;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

@Slf4j
@Controller
@RequestMapping("/weChatPay")
public class WeChatPayController {

    @Autowired
    private RechargeRecordRepository rechargeRecordRepository;

    @Autowired
    private MemberRepository memberRepository;

    @Autowired
    private WeChatPayRequest weChatPayRequest;

    @Autowired
    private OrderRepository orderRepository;

    /**
     *
     * @param request
     * @param tradeId 交易id
     * @param tradeType 交易类型
     * @param totalMoney 充值金额
     * @return
     */
    @RequestMapping("/pay")
    @ResponseBody
    public AjaxResult<WxPay> pay(final HttpServletRequest request, final Long tradeId, final String tradeType, final Float totalMoney) {
        return AjaxUtils.process(new Func_T<WxPay>() {
            @Override
            public WxPay invoke() throws Exception {
                WxPay result = new WxPay();


                if (tradeId == null || tradeId == 0) {
                    result.setCode("701");
                    result.setMsg("交易号错误");
                    return result;
                }
                //查询商品
                Float money = totalMoney;
                String description = "";
                RechargeRecord rechargeRecord = null;
                //1：订单垫付；2：购买服务付费；3：购买周边产品
                if (StringUtils.isEmpty(tradeType)) {
                    result.setCode("702");
                    result.setMsg("交易类型错误");
                    return result;
                } else {
                    if ("1".equals(tradeType)) {
                        //1:订单垫付，包括单次续费和合同收费，此时rechargeRecord已存在，传入orderId
                        Order order = orderRepository.findOne(tradeId);
                        if (order == null) {
                            result.setCode("703");
                            result.setMsg("未发现订单信息");
                            return result;
                        } else {
                            rechargeRecord = order.getRechargeRecord();
                            money = rechargeRecord.getMoney();
                            description = order.getId() + "垫付费用";
                        }
                    } else if("2".equals(tradeType)) {
                        //购买服务，包括购买单次服务和会员，订单信息已经到saleController中生成
                        rechargeRecord = rechargeRecordRepository.findOne(tradeId);
                        if (rechargeRecord == null) {
                            result.setCode("703");
                            result.setMsg("未发现订单信息");
                            return result;
                        } else {
                            money = rechargeRecord.getMoney();
                            description = rechargeRecord.getDescription();
                            if(StringUtils.isEmpty(description)) {
                                description = rechargeRecord.getId() + "订单收费";
                            }
                        }
                    } else {
                        //TODO 购买周边产品
                    }
                }

                //暂时没有上架下架功能
                //else if( !"1".equals(orderInfo.getCommodity().getIsSelling())){
                //	json.put(Constants.RETURN_CODE_FEILD, Constants.RETURN_CODE_SERVER_INTERNAL_ERROR);
                //	json.put(Constants.RETURN_MESSAGE_FEILD, "商品已经下架");
                //	printJSONToClient(json);
                //	return null;
                //}

                //交易金额
                BigDecimal totalAmount = new BigDecimal(money);
                if (money <= 0) {
                    result.setCode("704");
                    result.setMsg("交易金额有误");
                    return result;
                }

                //商品描述
                String detail = "{'orderId:'" + rechargeRecord.getId() + ",'money':" + totalAmount + "}";
                //IP地址
                String ipStr = request.getRemoteAddr();
                //提交请求获取交易流水号
                Map<String, String> rst = weChatPayRequest.requestOrderFlow(rechargeRecord.getId().toString(), "1", totalAmount, description, detail, ipStr);
                if (rst != null && rst.get("return_code") != null && "SUCCESS".equals(rst.get("return_code").toString()) && rst.get("prepay_id") != null) {
                    //根据流水号生成支付签名
                    Map<String, Object> signMap = weChatPayRequest.getPaySignParams(rst.get("prepay_id").toString());
                    if (signMap == null) {
                        result.setCode("705");
                        result.setMsg("获取支付签名失败");
                        return result;
                    } else {
                        //返回签名信息
                        result.setCode("200");
                        result.setTradeNo(rechargeRecord.getId().toString());
                        result.setWxSign(signMap);
                    }
                } else {
                    StringBuilder errorMsg = new StringBuilder("获取交易流水号失败");
                    if (rst == null) {
                        errorMsg.append("(null flow result)");
                    } else {
                        errorMsg.append("[").append(rst.get("return_msg")).append(":").append(rst.get("return_code")).append("]");
                    }

                    result.setMsg(errorMsg.toString());
                    result.setCode("706");
                }
                return result;
            }
        });
    }


    @RequestMapping("/notify")
    @ResponseBody
    public String notify(final HttpServletRequest request) throws Exception {
        log.info("=====订单支付回调成功=====");
        InputStream inStream = request.getInputStream();
        ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = inStream.read(buffer)) != -1) {
            outSteam.write(buffer, 0, len);
        }
        String resultXml = new String(outSteam.toByteArray(), "utf-8");
        Map<String, String> params = weChatPayRequest.doXMLParse(resultXml);
        outSteam.close();
        inStream.close();

        SortedMap<String,Object> return_data = new TreeMap<String,Object>();
        if (!weChatPayRequest.isTenpaySign("UTF-8", params)) {
            // 支付失败
            log.info("=====支付失败=====");
            return_data.put("return_code", "FAIL");
            return_data.put("return_msg", "return_code不正确");
        } else {
            String orderId = params.get("out_trade_no");
            if (StringUtils.isEmpty(orderId)) {
                // 支付失败
                log.info("=====支付失败：获取订单id失败=====");
                return_data.put("return_code", "FAIL");
                return_data.put("return_msg", "return_code不正确");
            } else {
                log.info("=====订单id：" + orderId);
                orderId = weChatPayRequest.regetTradeNo(orderId);
                Long realOrderId = Long.valueOf(orderId);
                RechargeRecord recharge = rechargeRecordRepository.findOne(realOrderId);
                if(recharge != null) {
                    recharge.setIsPayed("1");
                    recharge.setStatus("2");
                    rechargeRecordRepository.save(recharge);

                    return_data.put("return_code", "SUCCESS");
                    return_data.put("return_msg", "OK");
                } else {
                    // 支付失败
                    log.info("=====支付失败：订单不存在=====");
                    return_data.put("return_code", "FAIL");
                    return_data.put("return_msg", "订单不存在");
                }
            }
        }

        return weChatPayRequest.getRequestXml(return_data);
    }
}
